<script setup lang="ts">
import type Node from 'element-plus/es/components/tree/src/model/node';

import type { Ref } from 'vue';

import type { IContextMenuItem } from '@vben-core/shadcn-ui';

import type {
  RasterDataSource,
  VectorDataSource,
} from '#/components/scene-editor';

import { computed, nextTick, ref, toRefs, watch } from 'vue';
import { useRouter } from 'vue-router';

import {
  ElBottomRight,
  ElCalendar,
  ElCircleClose,
  ElCirclePlus,
  ElClose,
  ElCopyDocument,
  ElDArrowLeft,
  ElEdit,
  ElLocationInformation,
  ElLock,
  ElMoreFilled,
  ElPosition,
  ElRemove,
  FluentSaveCopy24Regular,
  IconParkOutlineSettingWeb,
  LetsIconsMapLight,
  QuillHamburgerSidebar,
  QuillLabel,
  SvgClusterIcon,
  SvgHeatmapIcon,
  SvgPolygonIcon,
  SvgPolylineIcon,
  SvgRasterIcon,
  SvgScatterIcon,
} from '@vben/icons';

import { VbenContextMenu } from '@vben-core/shadcn-ui';
import { StorageManager } from '@vben-core/shared/cache';

import {
  ElButton,
  ElDivider,
  ElEmpty,
  ElIcon,
  ElInput,
  ElMessage,
  ElPopover,
  ElScrollbar,
  ElTooltip,
  ElTree,
} from 'element-plus';

import { sceneApi } from '#/api';
import { ServiceDataPanel } from '#/components/scene-editor';
import { useClickOutside } from '#/hooks';
import { useSceneStore } from '#/store';

import { AddToLayerDialog, AttrTableDialog } from './index';

const props = defineProps({
  menuWidth: {
    type: String,
    default: '65px',
  },
  layerList: {
    type: Array,
    default: () => [],
  },
  isLocked: {
    type: Boolean,
    default: true,
  },
});

const emit = defineEmits([
  'closeLayerPannel',
  'removeLayer',
  'openLayerPropertyDialog',
  'setLayerVisibility',
  'zoomToLayer',
  'dragLayer',
  'dragStart',
  'removeAllLayers',
  'addLayerGroup',
  'openRenameDialog',
  'addToLayer',
  'autoRenderLayer',
]);

const storageManager = new StorageManager({
  prefix: '',
  storageType: 'sessionStorage',
});

const layerTreeRef = ref();
const morePopoverRef: Ref<HTMLElement | null> = ref(null);
const moreMenuRef: Ref<HTMLElement | null> = ref(null);
const popShow = ref(false);
const isMorePopShow = ref(false);
const isAttrTableDialogShow = ref(false);
const showMask = ref(false);
const isToggleBtnShow = ref(false);
const router = useRouter();

// const rasterServiceData = reactive({
//   data: [] as RasterServiceData[]
// })
const isAddToLayerDialogShow = ref(false);
const currentDataSource = ref<RasterDataSource | VectorDataSource>();

const currentSelectedLayer = ref();
const sceneStore = useSceneStore();
const { layerList } = toRefs(props);
const treeKey = ref(0);
// 通过props指定children
const treeProps = {
  children: 'layers',
  // label: 'name',
  disabled: (_data: any, node: any) => {
    return node.isLeaf && node.parent.data.renderParams?.isAnimationOpen;
  },
};
const currentTreeId = ref('');
const currentNodeKey = ref('');
const layerPannelHeight = ref('74vh');
const checkedLayers = computed(() => {
  const result: any[] = [];
  layerList.value.forEach((item: any) => {
    if (item.organizationType === 'groupLayer') {
      const visibleLayers = item.layers
        .filter((layer: any) => layer.layout.visibility === 'visible')
        .map((layer: any) => layer.id);
      result.push(...visibleLayers);
    } else {
      if (item.layout.visibility === 'visible') {
        // result.push(item.layerName); // 如果不唯一可用其他唯一标识字段代替
        result.push(item.id);
      }
    }
  });
  return result;
});
const layersLength = computed(() => {
  let length = 0;
  layerList.value.forEach((layeritem: any) => {
    if (layeritem.organizationType === 'singleLayer') {
      length++;
    } else {
      length += layeritem.layers.length;
    }
  });

  return length;
});
const zoomToLayer = (layer: any) => {
  currentSelectedLayer.value
    ? emit('zoomToLayer', layer)
    : ElMessage.info('未选择图层！');
};
const handleOpenAttrTable = () => {
  // 底图没有renderType
  if (
    currentSelectedLayer.value.renderType &&
    currentSelectedLayer.value.renderType[1] === 'cluster'
  ) {
    ElMessage.error('聚合图层数据源已变更，暂不支持查看属性表！');
    return;
  }
  isAttrTableDialogShow.value = true;
};
const renameLayer = () => {
  if (currentSelectedLayer.value === undefined) {
    ElMessage.info('未选择图层（组）！');
  } else {
    // OpenRenameDialog.value = true
    // currentName.value = currentSelectedLayer.value.name
    currentSelectedLayer.value.isRenaming = true;
    setTimeout(() => {
      nextTick(() => {
        const renameInput = document.querySelector('#renaming') as any;
        // console.log('dom', input);
        renameInput.focus();
      });
    }, 1);
    // emit('openRenameDialog', currentSelectedLayer.value)
  }
};
const isInGroupLayer = (layer: any) => {
  const layers = sceneStore.currentSceneConfig.layers;
  for (const layer_ of layers) {
    // const layer = array[i];
    if (layer_.organizationType === 'groupLayer' && layer_.layers.length > 0) {
      // 在 groupLayer 类型的元素的 layers 属性中查找
      for (let j = 0; j < layer_.layers.length; j++) {
        if (layer_.layers[j].id === layer.id) {
          return true;
        }
      }
    }
  }
  return false;
};
const removeLayer = () => {
  if (currentSelectedLayer.value === undefined) {
    ElMessage.info('未选择图层（组）！');
  } else {
    emit(
      'removeLayer',
      currentSelectedLayer.value,
      isInGroupLayer(currentSelectedLayer.value),
    );
  }
};
const editLayer = (layer: any) => {
  if (!currentSelectedLayer.value) {
    ElMessage.info('未选择图层！');
    return;
  }
  // if (currentSelectedLayer.value.renderType?.[1] === 'imageRasterRender') {
  //   ElMessage.error('暂不支持编辑图片图层！')
  //   return
  // }
  emit('openLayerPropertyDialog', layer);
};
const getMenus = (data: any): IContextMenuItem[] =>
  [
    {
      key: 'zoomToLayer',
      text: '缩放至图层',
      icon: ElLocationInformation,
      show: data.organizationType === 'singleLayer',
      handler: () => zoomToLayer(data),
    },
    {
      key: 'openAttrTable',
      text: '打开属性表',
      icon: ElCalendar,
      show: data.organizationType === 'singleLayer' && data.type !== 'raster',
      handler: () => handleOpenAttrTable(),
    },
    {
      key: 'rename',
      text: '重命名',
      icon: ElEdit,
      separator: true,
      show: true,
      handler: () => renameLayer(),
    },
    {
      key: 'remove',
      text: data.organizationType === 'singleLayer' ? '移除图层' : '移除图层组',
      icon: ElPosition,
      separator: true,
      handler: removeLayer,
      show: true,
    },
    {
      key: 'attr',
      text: '属性',
      icon: IconParkOutlineSettingWeb,
      handler: () => editLayer(data),
      show: true,
    },
  ].filter((item) => item.show);

// const layerListTree = computed(() => {
//   return layerList.value.map((layer: any) => {
//     if (layer.organizationType === 'groupLayer' && layer.layers.length > 0) {
//       layer.layers.forEach((subLayer: any) => {
//         subLayer.disabled = true
//       })
//       return layer
//     } else {
//       return layer
//     }
//   })
// })
// const transformLayersToTreeData = (layers: any) => {
//   const treeData = [] as any;
//   layers.value.forEach((item: any) => {
//     const node = {
//       id: item.id,
//       label: item.name,
//       children: [] as any
//     }
//     if (item.organizationType === "singleLayer") {
//       treeData.push(node);
//     } else if (item.organizationType === "groupLayer") {
//       item.layers.forEach((subLayer: any) => {
//         node.children.push({
//           id: subLayer.id,
//           label: subLayer.name
//         })
//       })
//       treeData.push(node)
//     }
//   })

//   return treeData
// }
watch(
  () => layersLength,
  () => {
    // console.log('图层列表', layerList.value);
    // layerTree.value = transformLayersToTreeData(layerList)
    treeKey.value++;
    let isCurrentLayerExist = false;
    if (!currentSelectedLayer.value) {
      return;
    }
    layerList.value.forEach((layerItem: any) => {
      if (layerItem.organizationType === 'singleLayer') {
        if (layerItem.id === currentSelectedLayer.value.id) {
          isCurrentLayerExist = true;
        }
      } else {
        layerItem.layers.forEach((sublayer: any) => {
          if (sublayer.id === currentSelectedLayer.value.id) {
            isCurrentLayerExist = true;
          }
        });
      }
    });
    if (!isCurrentLayerExist) {
      currentSelectedLayer.value = undefined;
    }
  },
  { deep: true },
);

const handleCloseMoreMenu = () => {
  if (currentSelectedLayer.value?.showMore) {
    delete currentSelectedLayer.value.showMore;
    nextTick(() => {
      morePopoverRef.value?.hide();
    });
  }
};

useClickOutside(moreMenuRef, handleCloseMoreMenu);
const importScene = async () => {
  const userId = storageManager.getItem<string>('userId') as string;
  const { sceneId } = storageManager.getItem<Record<string, any>>(
    'editingScene',
  ) as { sceneId: string };
  // router.push()
  const {
    id,
    name,
    type,
    thumbnail,
    createdUser,
    editCount,
    createdTime,
    updatedTime,
    isLocked,
    permissionRange,
  } = await sceneApi.importScene(userId, sceneId);
  const scene = {
    sceneId: id,
    sceneName: name,
    sceneType: type,
    sceneImg: thumbnail,
    userId: createdUser,
    editCount,
    createdTime,
    lastUpdatedTime: updatedTime,
    isLocked,
    permissionRange,
  };
  storageManager.setItem('editingScene', scene);
  // sceneStore.setEditingScene(scene)
  router.push(`/home/gdv-scene-editor/${scene?.sceneId}`);
  window.location.reload();
  ElMessage.success('导入成功');
};

const handleBeforeAddToLayer = (
  source: RasterDataSource | VectorDataSource,
  isPannelFixed: boolean,
) => {
  isAddToLayerDialogShow.value = true;
  if (!isPannelFixed) {
    popShow.value = false;
  }
  currentDataSource.value = source;
};
const handleAddToLayerConfirm = (layerName: any) => {
  emit('addToLayer', currentDataSource, layerName);
};

const closeLayerPannel = () => {
  emit('closeLayerPannel');
};

const removeAllLayers = () => {
  emit('removeAllLayers');
};
const dragLayer = (node: any, aimNode: any, direction: any, _event: any) => {
  emit('dragLayer', node.data, aimNode.data, direction);
};
const dragStart = (_node: any, _event: any) => {
  emit('dragStart');
};

const handleCheckedChange = (
  val: any,
  { checkedKeys }: { checkedKeys: string[] },
) => {
  // emit('setLayerVisibility', val.layerConfig.id, isChecked ? 'visible' : 'none')
  // 新模式下
  emit(
    'setLayerVisibility',
    val,
    checkedKeys.includes(val.id) ? 'visible' : 'none',
  );
};
const handleNodeClick = (data: any, node: Node) => {
  // console.log(data);
  // console.log(node);
  // 关闭更多菜单
  if (isMorePopShow.value) {
    handleCloseMoreMenu();
    isMorePopShow.value = false;
  }

  // 清除上一个节点的选中状态（如果存在）
  const lastNode =
    currentTreeId.value && layerTreeRef.value.getNode(currentTreeId.value);
  if (lastNode && lastNode.isCurrent) {
    lastNode.isCurrent = false;
  }

  // 高亮当前选中
  node.isCurrent = true;

  // 处于动画状态的节点，不能选中
  if (node.isLeaf && node.parent.data.renderParams?.isAnimationOpen) {
    node.isCurrent = false;
    // console.log(currentTreeId.value);
    // 值更改，触发watch
    currentNodeKey.value = '';
    // 还原之前的高亮节点
    nextTick(() => {
      currentNodeKey.value = currentTreeId.value;
    });
    return;
  }
  currentTreeId.value = data.id;
  currentSelectedLayer.value = data;

  // console.log('当前图层是否在组内', isInGroupLayer(data));
};

const handleNodeContextmenu = (_event: any, data: any, node: Node) => {
  // 右击选中
  handleNodeClick(data, node);
  // 高亮当前选中
  // node.isCurrent = true;
  nextTick(() => {
    currentNodeKey.value = currentTreeId.value;
  });
};

const handleAllowDrop = (draggingNode: any, dropNode: any, type: any) => {
  // console.log(draggingNode, dropNode, type);
  // 不允许图层放置到组内图层的某个图层
  if (dropNode.data.organizationType === 'singleLayer') {
    if (
      draggingNode.data.organizationType === 'groupLayer' &&
      isInGroupLayer(dropNode.data)
    ) {
      return false;
    }
    if (type === 'inner') {
      return false;
    }
    if (isInGroupLayer(dropNode.data)) {
      // 有动画时禁止拖拽
      return !dropNode.parent.data.renderParams?.isAnimationOpen;
    }
    return true;
  } else {
    // 不允许图层组放入图层组内
    if (draggingNode.data.organizationType === 'groupLayer') {
      return type !== 'inner';
    } else {
      // 有动画时禁止拖拽
      return type === 'inner'
        ? !dropNode.data.renderParams?.isAnimationOpen
        : true;
    }
  }
};

const getEmptyGroupNum = () => {
  let count = 0;
  sceneStore.currentSceneConfig.layers.forEach((layer: any) => {
    if (layer.organizationType === 'groupLayer' && layer.layers.length === 0) {
      count++;
    }
  });
  return count;
};
const handleAllowDrag = (draggingNode: any) => {
  // 有动画时禁止拖拽
  if (draggingNode.parent.data.renderParams?.isAnimationOpen) {
    ElMessage.error('当前图层处于动画中，请关闭后移动！');
    return false;
  }
  if (draggingNode.data.type === 'Style-OD') {
    ElMessage.error('该风格类型图层暂不支持移动！');
    return false;
  }
  if (getEmptyGroupNum() > 1) {
    ElMessage.error('置留多个空图层组，请移除多余的空图层组！');
    return false;
  } else {
    return true;
  }
};

const addLayerGroup = () => {
  if (getEmptyGroupNum() > 0) {
    ElMessage.error('请勿重复添加空图层组！');
  } else {
    emit('addLayerGroup');
  }
};
// const startRenaming = (source: DataSource) => {
//   source.isRenaming = true
//   nextTick(() => {
//     const renameInput = document.getElementById('renaming') as any
//     // console.log('dom', input);
//     renameInput.focus()
//   })
// }

const isBaseMap = (layer: any) => {
  return !!(
    typeof layer.source === 'string' && layer.source.includes('mapSource')
  );
};

const isMap = (layer: any) => {
  return !!(isBaseMap(layer) && layer.id.includes('mapLayer'));
};

const isAnnotate = (layer: any) => {
  return !!(isBaseMap(layer) && layer.id.includes('annotate'));
};

const handleCloseAttrTableDialog = () => {
  isAttrTableDialogShow.value = false;
};

const getCheckedKeys = () => {
  return layerTreeRef.value.getCheckedKeys(false);
};

const setCheckedKeys = (keys: any) => {
  layerTreeRef.value.setCheckedKeys(keys, false);
};

// const setChecked = (key: string, checked: boolean, deep: boolean) => {
//   layerTreeRef.value.setChecked(key, checked, deep);
// };

const handleMouseEnter = (_el: any, data: any) => {
  data.showIcon = true;
};

const renameLayerAfterSelect = (_event: any, data: any, node: Node) => {
  handleNodeClick(data, node);
  renameLayer();
};

defineExpose({ getCheckedKeys, setCheckedKeys });

// const autoRenderLayer = (layer: any) => {
//   emit('autoRenderLayer', layer);
// };
</script>

<template>
  <!-- 禁用图层面板的浏览器右击事件 -->
  <div
    class="all"
    oncontextmenu="return false"
    @mouseover="
      showMask = true;
      isToggleBtnShow = true;
    "
    @mouseleave="
      showMask = false;
      isToggleBtnShow = false;
    "
  >
    <div class="mask" v-if="isLocked && showMask">
      <div class="mask-content">
        <ElIcon size="30">
          <ElLock />
        </ElIcon>
        <p>当前为预览模式，导入我的场景后即可编辑</p>
        <ElButton
          type="primary"
          :icon="ElBottomRight"
          size="default"
          @click="importScene()"
        >
          导入
        </ElButton>
      </div>
    </div>
    <div class="toggle-btn" v-show="isToggleBtnShow" @click="closeLayerPannel">
      <ElIcon size="16">
        <ElDArrowLeft />
      </ElIcon>
    </div>
    <div class="custom-tree-container">
      <div class="header">
        <div class="title">
          <span>图层</span>
        </div>
        <div class="btnCon" title="收起图层面板" @click="closeLayerPannel">
          <ElIcon size="20" class="backBtn">
            <ElClose />
          </ElIcon>
        </div>
      </div>
      <ElDivider style="margin-top: 0; margin-bottom: 0" />
      <div class="data-source-panel">
        <ElPopover
          placement="right-start"
          :width="430"
          trigger="click"
          :hide-after="0"
          :visible="popShow"
          :offset="210"
          :popper-style="{ padding: '0px' }"
          @blur="popShow = false"
        >
          <template #reference>
            <ElButton
              class="layer-control-btn"
              type="primary"
              :icon="popShow ? ElCircleClose : ElCirclePlus"
              size="large"
              text
              @click.stop="popShow = !popShow"
            >
              {{ popShow ? '关闭面板' : '添加图层' }}
            </ElButton>
          </template>
          <ServiceDataPanel
            v-if="popShow"
            @close-panel="popShow = false"
            @before-add-to-layer="handleBeforeAddToLayer"
          />
        </ElPopover>
        <ElButton
          class="layer-control-btn"
          type="danger"
          :icon="ElRemove"
          size="large"
          text
          @click="removeAllLayers"
        >
          清空图层
        </ElButton>
      </div>
      <ElDivider style="margin-top: 0; margin-bottom: 0" />
      <div class="layerEditCon">
        <!-- <el-button type="primary" @click="addLayer" :icon="Plus" circle title="图层添加" />
        <el-button type="success" :icon="ElCopyDocument" circle title="添加图层组" disabled />
        <el-button type="primary" :icon="Upload" circle title="图层导出" disabled />
        <el-button type="danger" @click="removeLayer" :icon="Delete" circle title="清空图层" /> -->
        <div class="layerTips">
          <span v-if="currentSelectedLayer">
            {{
              currentSelectedLayer.organizationType === 'singleLayer'
                ? '当前选中图层：'
                : '当前选中图层组：'
            }}
            <ElTooltip :content="currentSelectedLayer.name" placement="top">
              <span style="text-decoration: underline">{{
                currentSelectedLayer.name
              }}</span>
            </ElTooltip>
          </span>
          <span v-else>未选择图层（组）</span>
          <!-- <span :title="currentSelectedLayer.layerName">{{ currentSelectedLayer ? '当前选中图层：' +
            currentSelectedLayer.layerName : '未选择图层' }}</span> -->
        </div>
        <ElDivider
          direction="vertical"
          style="margin-right: 5px; margin-left: 5px"
        />
        <ElButton
          class="layer-btn"
          type="primary"
          :icon="ElCopyDocument"
          size="default"
          text
          @click="addLayerGroup"
        >
          添加图层组
        </ElButton>
        <ElDivider
          direction="vertical"
          style="margin-right: 0; margin-left: 10px"
        />
        <!-- <el-button class="layer-btn" type="danger" :icon="CircleCloseFilled" size="default" text
          @click="removeAllLayers">清空图层</el-button> -->
      </div>
      <ElDivider style="margin-top: 0; margin-bottom: 5px" />

      <ElScrollbar
        :style="`height: ${layerPannelHeight}`"
        :max-height="layerPannelHeight"
      >
        <div class="treeCon">
          <ElTree
            ref="layerTreeRef"
            v-if="layerList.length > 0"
            class="custom-tree"
            :key="treeKey"
            :data="layerList"
            :props="treeProps"
            show-checkbox
            node-key="id"
            :default-checked-keys="checkedLayers"
            default-expand-all
            :expand-on-click-node="false"
            @check="handleCheckedChange"
            @node-click="handleNodeClick"
            @node-contextmenu="handleNodeContextmenu"
            :allow-drop="handleAllowDrop"
            :allow-drag="handleAllowDrag"
            draggable
            @node-drop="dragLayer"
            @node-drag-start="dragStart"
            :current-node-key="currentNodeKey"
          >
            <template #default="{ node, data }">
              <VbenContextMenu :menus="getMenus" :handler-data="data">
                <div class="custom-tree-node">
                  <div
                    class="node-name"
                    v-if="data.organizationType === 'singleLayer'"
                    :class="{
                      disabled: node.parent.data.renderParams?.isAnimationOpen,
                    }"
                  >
                    <ElIcon size="15">
                      <SvgClusterIcon
                        v-if="
                          data.type === 'circle' &&
                          data.renderType[1] === 'cluster'
                        "
                      />
                      <SvgScatterIcon
                        v-else-if="
                          data.type === 'circle' &&
                          data.renderType[0] === 'BasicMapping'
                        "
                      />
                      <SvgPolylineIcon v-else-if="data.type === 'line'" />
                      <SvgPolygonIcon v-else-if="data.type === 'fill'" />
                      <SvgHeatmapIcon v-else-if="data.type === 'heatmap'" />
                      <LetsIconsMapLight v-else-if="isMap(data)" />
                      <QuillLabel v-else-if="isAnnotate(data)" />
                      <SvgRasterIcon v-else-if="data.type === 'raster'" />
                    </ElIcon>
                    <ElDivider
                      direction="vertical"
                      border-style="hidden"
                      style="margin: 0 2px"
                    />
                    <span v-if="!data.isRenaming" class="text-sm">{{
                      data.name
                    }}</span>
                    <ElInput
                      class="renaming-single"
                      v-model="data.name"
                      v-else
                      clearable
                      @blur="data.isRenaming = false"
                      id="renaming"
                    />
                  </div>
                  <div class="node-name" v-else>
                    <ElIcon size="15">
                      <TdesignAnimation1Filled
                        v-if="data.renderParams?.isAnimationOpen"
                      />
                      <QuillHamburgerSidebar v-else />
                    </ElIcon>
                    <ElDivider
                      direction="vertical"
                      border-style="hidden"
                      style="margin: 0 2px"
                    />
                    <span style="font-size: 15px; font-weight: 700">
                      图层组-
                    </span>
                    <span
                      v-if="!data.isRenaming"
                      style="font-size: 15px; font-weight: 700"
                      >{{ data.name }}
                    </span>
                    <ElInput
                      class="renaming-group"
                      v-model="data.name"
                      v-else
                      clearable
                      @blur="data.isRenaming = false"
                      id="renaming"
                    />
                  </div>
                  <div
                    class="node-icon"
                    @mouseenter="(el: any) => handleMouseEnter(el, data)"
                    @mouseleave="delete data.showIcon"
                  >
                    <ElTooltip
                      content="重命名"
                      placement="top"
                      :hide-after="0"
                      :enterable="false"
                    >
                      <ElIcon
                        size="17"
                        v-show="data.showIcon"
                        @click="renameLayerAfterSelect($event, data, node)"
                      >
                        <ElEdit />
                      </ElIcon>
                    </ElTooltip>
                    &nbsp;
                    <ElTooltip
                      content="复制图层"
                      placement="top"
                      :hide-after="0"
                      :enterable="false"
                    >
                      <ElIcon size="17" v-show="data.showIcon">
                        <FluentSaveCopy24Regular />
                      </ElIcon>
                    </ElTooltip>
                    <ElPopover
                      ref="morePopoverRef"
                      placement="bottom-start"
                      :width="100"
                      trigger="click"
                      transition="none"
                      :hide-after="0"
                      :visible="data.showMore"
                      :popper-style="{ padding: '3px 0px', minWidth: '100px' }"
                      @blur="data.showMore = false"
                      @click.stop="data.showMore = !data.showMore"
                      @show="isMorePopShow = true"
                    >
                      <template #reference>
                        <div
                          class="more-box"
                          :class="[{ 'more-box-active': data.showMore }]"
                          @click="data.showMore = !data.showMore"
                        >
                          <ElIcon>
                            <ElMoreFilled />
                          </ElIcon>
                        </div>
                      </template>
                      <template #default>
                        <div
                          ref="moreMenuRef"
                          style="width: 100%; height: 100%"
                          @click="
                            handleCloseMoreMenu();
                            isMorePopShow = false;
                          "
                        >
                          <div
                            class="more-menu"
                            v-show="
                              currentSelectedLayer?.organizationType ===
                              'singleLayer'
                            "
                            @click="zoomToLayer(currentSelectedLayer)"
                          >
                            <ElIcon>
                              <ElLocationInformation />
                            </ElIcon>
                            &nbsp;缩放至
                          </div>
                          <div
                            class="more-menu"
                            v-show="
                              currentSelectedLayer?.organizationType ===
                              'singleLayer'
                            "
                            @click="handleOpenAttrTable"
                          >
                            <ElIcon> <ElCalendar /> </ElIcon>&nbsp;属性表
                          </div>
                          <div class="more-menu" @click="removeLayer">
                            <ElIcon> <ElPosition /> </ElIcon>&nbsp;移除
                          </div>
                          <div
                            class="more-menu"
                            @click="editLayer(currentSelectedLayer)"
                          >
                            <ElIcon>
                              <IconParkOutlineSettingWeb />
                            </ElIcon>
                            &nbsp;编辑
                          </div>
                        </div>
                      </template>
                    </ElPopover>
                  </div>
                </div>
              </VbenContextMenu>
            </template>
          </ElTree>
          <ElEmpty description="您还未添加图层" v-else :image-size="120" />
          <!-- <template #default="{ node, data }">
            <span class="custom-tree-node">
              <span v-if="data.organizationType === 'singleLayer'">
                <svg class="icon" aria-hidden="true">
                  <use v-if="data.type === 'circle'" xlink:href="#icon-dian"></use>
                  <use v-else-if="data.type === 'line'" xlink:href="#icon-poly-line"></use>
                  <use v-else-if="data.type === 'fill'" xlink:href="#icon-polygon"></use>
                  <use v-else-if="data.type === 'STYLE-HEATMAP'" xlink:href="#icon-relitu"></use>
                </svg>
                <el-divider direction="vertical" border-style="hidden"></el-divider>
                <span>{{ data.name }}</span>
              </span>
              <span v-else>
                <svg class="icon" aria-hidden="true">
                  <use xlink:href="#icon-dian"></use>
                </svg>
                <el-divider direction="vertical" border-style="hidden"></el-divider>
                <span>{{ data.name }}</span>
              </span>
            </span>
          </template> -->
          <!-- </el-tree> -->
        </div>
      </ElScrollbar>
    </div>
  </div>

  <AddToLayerDialog
    v-if="isAddToLayerDialogShow"
    :is-add-to-layer-dialog-show="isAddToLayerDialogShow"
    :current-data-source="currentDataSource"
    @close-add-to-layer-dialog="isAddToLayerDialogShow = false"
    @add-to-layer-confirm="handleAddToLayerConfirm"
  />
  <!-- 预览对话框 -->
  <AttrTableDialog
    v-if="isAttrTableDialogShow"
    :is-dialog-show="isAttrTableDialogShow"
    :current-selected-layer="currentSelectedLayer"
    :current-data-source="currentDataSource"
    @close-attr-table-dialog="handleCloseAttrTableDialog"
  />
</template>

<style scoped lang="scss">
.all {
  /* margin-left: v-bind(menuWidth); */

  /* position: fixed; */

  /* z-index: 999; */
  position: relative;
  display: flex;
  flex: 1;
  flex-direction: column;
  width: 100%;

  /* height: 88.5vh;
  width: 300px; */

  /* width: 396px; */
  height: 100%;
  background-color: #f8f8f8;

  .mask {
    position: absolute;
    top: 0;
    left: 0;

    /* 半透明黑色 */
    z-index: 10;

    /* 确保遮罩层在其他内容之上 */

    /* pointer-events: none; */

    /* 避免遮罩层阻止点击事件 */
    display: flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    height: 100%;
    background: rgb(0 0 0 / 50%);
  }

  .toggle-btn {
    position: absolute;
    top: 50%;
    right: 0;
    z-index: 11;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 20px;
    height: 30px;
    background-color: rgb(255 255 255);
    border: #e4e4e4 solid 1px;
    border-radius: 5px;
    box-shadow: 0 4px 6px rgb(0 0 0 / 10%);
    transition: all 0.2s ease;
    transform: translateX(50%);

    &:hover {
      width: 30px;
      cursor: pointer;
      background-color: #f2f2f2;
      box-shadow: 0 6px 10px rgb(0 0 0 / 20%);
    }
  }
}

.mask-content {
  color: white;
  text-align: center;

  p {
    font-family: Arial, Helvetica, sans-serif;
    font-size: 1em;
  }
}

.custom-tree-container {
  width: 100%;
  height: 100%;

  /* border-right: 1px solid #999; */
}

:deep(.el-tree-node__content) {
  box-sizing: border-box;
  width: calc(310px - var(--padding-left, 0));

  /* 使用自定义属性计算宽度 */
  height: 50px;
  padding: 10px 0;
  background-color: #fff; // background-color: #0000000a;

  /* 添加过渡效果 */
  border-radius: 5px;
  // border: 1px solid rgba(175, 175, 175, 0.5);
  transition: border-color 0.3s;

  &:hover {
    background-color: #edecec;
  }
}

.custom-tree-node {
  // flex: 1;
  display: flex;
  align-items: center;
  justify-content: space-between;
  width: 100%;
  height: 100%;
  padding-right: 8px;
  // display: grid;
  // grid-template-columns: auto min-content;
  // overflow: hidden;
  font-size: 14px;

  .node-name {
    display: flex;
    flex: 1;
    align-items: center;
    width: 155px;
    height: 100%;

    & > span:last-child {
      overflow: hidden;
      text-overflow: ellipsis;
      white-space: nowrap;
    }
  }

  .node-icon {
    display: flex;
    align-items: center;
    width: 57px;
    height: 100%;

    .more-box {
      position: absolute;
      right: 0;
      display: flex;
      align-items: center;
      justify-content: center;
      width: 20px;
      height: 48px;
      border-radius: 5px;

      // background-color: red;
      &:hover {
        box-sizing: border-box;
        color: #151515;
        border: #007ac3 solid 1px;
      }
    }

    .more-box-active {
      box-sizing: border-box;
      color: #151515;
      border: #007ac3 solid 1px;
    }

    .el-icon {
      &:not(:last-child) {
        width: 20px;
        height: 20px;

        &:hover {
          // color: #3f9eff;
          color: #151515;
          // border: #3f9eff solid 1px;
          // box-sizing: border-box;
          // border-radius: 5px;
        }
      }

      &:last-child {
        // position: absolute;
        // right: 5px;
        transform: rotate(90deg);
      }
    }
  }
}

.more-menu {
  display: flex;
  align-items: center;
  justify-content: left;
  width: 100%;
  height: 25px;
  padding: 0 10px;
  color: #545454;
  cursor: pointer;

  &:hover {
    color: #000;
    background-color: #edecec;
  }
}

:deep(.renaming-single .el-input__inner) {
  width: 120px;
  font-size: 14px;
}

:deep(.renaming-group .el-input__inner) {
  width: 50px;
  font-size: 16px;
}

.icon {
  width: 1em;
  height: 1em;
  overflow: hidden;

  /* vertical-align: -0.15em; */
  fill: currentcolor;
}

.el-tree {
  background-color: #f8f8f8;
}

:deep(.el-tree-node > .el-tree-node__children) {
  .el-tree-node__content {
    border-top: 1px dashed rgb(175 175 175 / 50%);
    // border-top: none;
    border-top-left-radius: 0;
    border-top-right-radius: 0;
  }
}

:deep(.el-tree > .el-tree-node > .level-2) {
  padding-top: 20px;
}

// :deep(.el-tree-node.is-current) {
//   position: relative;
//   /* 确保为伪元素定位提供上下文 */
// }

/* 选中当前node的样式 */
:deep(.el-tree-node.is-current) {
  /* 确保为伪元素定位提供上下文 */
  // position: relative;

  > .el-tree-node__content {
    box-sizing: border-box;
    font-weight: 600;
    color: #409eff;
    background-color: var(--el-color-primary-light-9);
    border-left: #3f9eff 3px solid;
    border-radius: 5px;

    // &::before {
    //   content: "";
    //   display: inline-block;
    //   width: 3px;
    //   height: 50px;
    //   background-color: #2f89fc;
    //   position: absolute;
    //   left: 0;
    //   top: 0;
    // }
  }
}

/* 聚焦当前node的样式（便于右击选中高亮）（会有bug，导致失去焦点时，高亮被清除） */
// :deep(.el-tree-node:focus > .el-tree-node__content) {
//   background-color: var(--el-color-primary-light-9);
//   color: #3f9eff;
//   font-weight: 700;
//   border-radius: 5px;
//   box-sizing: border-box;
//   border-left: #3f9eff 3px solid;
// }

.a {
  color: blue;
}

:deep(.el-scrollbar .el-scrollbar__wrap) {
  overflow-x: hidden;
}

:deep(.el-tree > .el-tree-node) {
  display: inline-block;
  min-width: 100%;
  margin: 5px 0;
  border: 1px solid rgb(175 175 175 / 50%);
  border-radius: 5px;
}

.header {
  box-sizing: border-box;
  display: flex;
  align-items: center;
  justify-content: space-between;
  width: 100%;
  height: 55px;
  // color: white;
  padding: 0 0 0 20px;
  background-color: #fff;
  border-bottom: 1px solid rgb(175 175 175 / 50%);
}

.title {
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 18px;
  font-weight: bold;
  color: #555;

  /* color: rgb(73, 70, 70); */
}

.btnCon {
  position: relative;
  box-sizing: border-box;
  width: 54px;
  height: 54px;
  color: #545454;
  // margin-left: 10px;

  &:hover {
    font-weight: 700;
    color: #2f6c90;
    cursor: pointer;
    // transform: scale(1.2);
    background-color: #f6f6f6;
    border: 1px solid rgb(63 158 255);
  }
}

.treeCon {
  padding: 10px 15px;
}

.backBtn {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}

.layerEditCon {
  box-sizing: content-box;
  display: flex;
  align-items: center;
  justify-content: space-evenly;

  /* width: 100%; */
  height: 2%;
  padding: 10px 5px;

  /* padding-right: 5px; */
}

.layerTips {
  width: 60%;

  /* 禁止换行 */
  overflow: hidden;

  /* font-style: italic; */
  font-size: 14px;
  text-align: center;

  /* 隐藏超出部分 */
  text-overflow: ellipsis;
  white-space: nowrap;

  /* text-decoration: underline; */

  /* 使用省略号显示超出内容 */

  /* display: flex;
  justify-content: space-evenly;
  text-align: center;
  align-items: center; */
}

.layer-btn {
  width: 20%;
  font-size: 13px;
  cursor: pointer;
}

:deep(.layer-btn.el-button--primary.is-text:hover) {
  font-weight: 700;
  transform: scale(1.05);
}

:deep(.layer-btn.el-button--danger.is-text:hover) {
  font-weight: 700;
  transform: scale(1.05);
}

.dialog-footer button:first-child {
  margin-right: 10px;
}

/* :deep(.el-dialog) {
  box-shadow: 0px 0px 50px rgba(0, 0, 0, 0.5);
  border-radius: 20px;
  height: auto;
} */

.data-source-panel {
  display: flex;
  align-items: center;
  justify-content: space-between;
  width: 100%;
  height: 45px;
  padding: 10px 0;
}

.layer-control-btn {
  width: 40%;
  font-size: 16px;

  /* background-color: #ccc; */

  /* 默认背景色 */

  /* border: 1px solid #3f9eff; */

  /* transition: background-color 0.3s; */
}

/* text类型的btn设置hover */
:deep(.layer-control-btn.el-button--primary.is-text:hover) {
  /* background-color: rgba(63, 158, 255, 0.5); */

  /* color: white; */
  font-weight: 700;
  border: 1px solid rgb(63 158 255);
}

:deep(.layer-control-btn.el-button--danger.is-text:hover) {
  font-weight: 700;
  border: 1px solid #f56c6c;
}

// .layerContentScrollbar {
//   height: v-bind(layerPannelHeight);
//   // flex: 1;
// }

/* 隐藏横向滚动条 */
// :deep(.layerContentScrollbar .is-horizontal) {
//   display: none !important;
// }

.mybtn {
  width: 80px;
  height: 30px;
  font-weight: bolder;
  letter-spacing: 1px;
  border-radius: 3px;
}

/* 禁用状态的样式 */
:deep(.el-tree-node__content:has(.disabled)) {
  cursor: not-allowed;

  /* 将鼠标指针改为禁止符号 */
  opacity: 0.7;

  /* 降低元素的不透明度 */

  /* pointer-events: none; */

  /* 阻止鼠标事件，如点击 */
}
</style>
